#!/usr/bin/env python
# vim: set fileencoding=UTF-8

###############################################################################
#
# filename:  install.py
#
# purpose:   Install management
#
# author(s): Alessandro Molari (mola89.molarulez.com)
#            Luca Molari
#
# license:   This file is licensed under the GPLv2
#            For more informations read:
#            http://www.gnu.org/licenses/gpl-2.0.txt
#
# part of:   This file is a part of the XazeInstaller
#
###############################################################################


"""
Install management
"""



import os
import string
import struct



class FinishInstallException:
    def __init__(self, currentconfig):
        self.currentconfig = currentconfig
    def __str__(self):
        return "\n>>> Installation finished after installing %s\n" % (self.currentconfig, )


class Installer:

    def __init__(self, startdir, currentuser):
        
        self.startdir = startdir
        self.currentuser = currentuser


    def install(self):
        print "\n>>> Installation started\n"

        # directory that contains all config sections
        configs_path = os.path.abspath(
                                os.path.join(self.startdir, "configs"))

        # management directory, it contains all installing and managing scripts
        management_path = os.path.abspath(
                                os.path.join(self.startdir, "management"))

        # xmlschema structure file for the config sections
        structschema_path = os.path.abspath( \
                os.path.join(os.path.join(management_path, "schema"), \
                                          "structure_schema.xml"))

        # set the automatic installation (non interactive) as False
        automatic = False
        
        # loop in each config section
        try:
            for dir in self._get_subdirs(configs_path):

                # name of the current config section
                confsect_name = "/".join(dir.split("/")[-1:])

                # xml structure file for the current config section
                struct_path = os.path.abspath(os.path.join(dir, \
                                                           "structure.xml"))
                
                # install the current config section and returns if the next
                #     config setion has to be automatic
                automatic = self._install_section("  ", dir, \
                                                  confsect_name, struct_path, \
                                                  structschema_path, automatic)
        
        except FinishInstallException as exc:
            print exc
        else:
            print "\n>>> Installation finished\n"

    def _install_section(self, is_space, dir, \
                         confsect_name, struct_path, \
                         structschema_path, automatic):

        print "\n%s>>> Installation of %s started" % (is_space, confsect_name)

        if automatic:
            self._process_section("%s  " % (is_space, ), dir, \
                                  confsect_name, struct_path, \
                                  structschema_path)
        else:
            inp = string.lower(raw_input(">>> Install %s ? [Y,n,exit,auto]" % \
                                 (confsect_name, )))
            if inp == "exit":
                raise FinishInstallException(confsect_name)
            elif not inp in ("n", "no"):
                if inp == "auto":
                    automatic = True
                self._process_section("%s  " % (is_space, ), \
                                      dir, confsect_name, \
                                      struct_path, structschema_path)
            else:
                print "\n%s>>> %s not installed\n" % \
                       (is_space, confsect_name, )
        
        print "%s>>> Installation of %s finished\n" % (is_space, confsect_name)

        return automatic


    def _process_section(self, ps_space, dir, \
                         confsect_name, struct_path, \
                         structschema_path):

            # structure management object
            config_struct = struct.Structure(ps_space, struct_path, \
                                             structschema_path, dir, \
                                             self.currentuser)

            # preinstall of 'confsect_name' config section
            try:
                print "%s>>> Started pre-install of %s" % (ps_space, confsect_name)
                preinstmod = __import__("preinstall.%s" % \
                                        (confsect_name), \
                                        fromlist=["main"])
            except ImportError:
                print "%s>>> Finished pre-install of %s (script not found)" % \
                        (ps_space, confsect_name)
            else:
                preinstmod.main("%s  " % (ps_space, ), \
                                self.startdir, \
                                self.currentuser)
                print "%s>>> Finished to execute pre-install of %s" % \
                        (ps_space, confsect_name)
            
            # install process
            print "%s>>> Started install of %s" % (ps_space, confsect_name)
            config_struct.process("%s  " % (ps_space, ))
            print "%s>>> Finished install of %s" % (ps_space, confsect_name)
            
            # postinstall of 'confsect_name' config section
            try:
                print "%s>>> Started post-install of %s" % (ps_space, confsect_name)
                pstinstmod = __import__("postinstall.%s" % \
                                        (confsect_name, ), \
                                        fromlist=["main"])
            except ImportError:
                print "%s>>> Finished post-install of %s (script not found)" % \
                        (ps_space, confsect_name)
            else:
                pstinstmod.main("%s  " % (ps_space, ), \
                                self.startdir, \
                                self.currentuser)
                print "%s>>> Finished to execute post-install of %s" % \
                        (ps_space, confsect_name, )      


    def _get_subdirs(self, dir):
        result = []
        for subdir in [d for d in os.listdir(dir) if d[0] != "."]:
            subdir = os.path.join(dir,subdir)
            if os.path.isdir(subdir):
                result.append(subdir)
        return result




if __name__ == "__main__":
    print "install executed"

